#include "processor.hpp"
#include "memory.hpp"

Reg<uint64_t> iregs(32, "00000000001111111111111111111111");
Reg<uint64_t> sregs(8, "10000000");
Reg<uint64_t> IMMs(4, "0000");
extern MemControl membus;
Control controler;
uint8_t CommandEN;
bool Priv;
bool Error;

// 处理器功能函数
static void CheckFlag(bool signA, bool signB, long long res) // 标记设置
{
	sregs[Status] &= 0xfffffffffffffff0; // 清空标志位
	if (res < 0)
		sregs[Status] |= 0x04;
	else if (res > 0)
		sregs[Status] |= 0xff;
	else
		sregs[Status] |= 0x01;
	if (signA && signB) // 判断溢出
	{
		bool signal = res > 0;
		if (signA ^ signal)
			sregs[Status] |= 0x08;
	}
}
template <typename T>
T ALU(uint8_t op) // 数值逻辑计算
{
	long long result = 0;
	switch (op)
	{ // 减法：减数取反
	case 0x11:
		IMMs[IY] = -IMMs[IY];
	case 0x10:
		result = IMMs[IX] + IMMs[IY];
		CheckFlag(((long long)IMMs[IX]) < 0, ((long long)IMMs[IY]) < 0, result);
		break;
	case 0x13:
		IMMs[IY] = -IMMs[IY];
	case 0x12:
		result = IMMs[IX] + IMMs[IY];
		CheckFlag(((long long)IMMs[IX]) < 0, ((long long)IMMs[IY]) < 0, result);
		break;
	case 0x20:
		IMMs[IX] &= IMMs[IY];
		break;
	case 0x21:
		IMMs[IX] |= IMMs[IY];
		break;
	case 0x22:
		IMMs[IX] ^= IMMs[IY];
		break;
	case 0x30:
		IMMs[IX] <<= IMMs[IY];
		break;
	case 0x31:
		IMMs[IX] >>= IMMs[IY];
		break;
	case 0x32:
		IMMs[IX] = ((long long)IMMs[IX]) >> IMMs[IY];
		break;
	case 0x33:
		IMMs[IX] = (IMMs[IX] << IMMs[IY]) | (IMMs[IX] >> (64 - (IMMs[IY] & 0x3f)));
		break;
	case 0x34:
		IMMs[IX] = (IMMs[IX] >> IMMs[IY]) | (IMMs[IX] << (64 - (IMMs[IY] & 0x3f)));
		break;
	}
	return (T)result;
}

// 寄存器函数设计
template <typename T>
Reg<T>::Reg()
{
	data = new pair<T, T>[1];
	size = 1;
}
template <typename T>
Reg<T>::Reg(int n, std::string s)
{
	size = n;
	data = new pair<T *, T *>[n];
	for (int i = 0; i < n; i++)
	{
		data[i].first = new T;
		if (s[i] == '0') // 单状态寄存器
			data[i].second = data[i].first;
		else // 双状态寄存器
			data[i].second = new T;
	}
}
template <typename T>
Reg<T>::~Reg()
{
	for (int i = 0; i < size; i++)
	{
		delete data[i].first;
		try
		{
			delete data[i].second;
		}
		catch (std::exception e) {}
	}
	delete[] data;
}
template <typename T>
T &Reg<T>::operator[](int index)
{
	return Priv ? *data[index].second : *data[index].first;
}
template <typename T>
T *Reg<T>::operator()(int index)
{
	return Priv ? data[index].second : data[index].first;
}

// 控制器函数设计
// 分类型的取指流程
inline void Control::idI() const
{
	switch (IR.list.opVal)
	{
		// 三元运算指令
	case 2:
		IMMs[IY] = iregs[IR.list.rs2];
		// 二元运算指令
	case 1:
		IMMs[IX] = iregs[IR.list.rs1];
		break;
		// 内存读写
	case 0x10:
	case 0x11:
		IMMs[IX] = iregs[IR.list.rs1];
		IMMs[IY] = IR.list.rs2;
		IMMs[IY] = IMMs[IY] << 16 + IR.list.imm;
		break;
	case 0x18:
	case 0x19:
		IMMs[IX] = IR.list.imm;
		break;
	case 0x20:
	case 0x21:
		IMMs[IX] = iregs[IR.list.rd];
		IMMs[IY] = IR.list.rs2;
		IMMs[IY] = IMMs[IY] << 16 + IR.list.imm;
		break;
	default: // 错误的指令
		Error = true;
		sregs[Cause] = 0xff01;
		return;
	}
}
// 指令流水线
inline void Control::fetch()
{
	IMMs[MAR] = sregs[0];
	membus.addtrans(Priv ? (R | X | P) : (R | X));
	if (Error)
		return;
	membus.read(8, true);
	sregs[0] += 8;
}
void Control::decode()
{
	if (Error) // 取指阶段错误
		return;
	IR.data = IMMs[MDR];
	if (!(IR.list.opType & CommandEN)) // 指令集未启用
	{
		Error = true;
		sregs[Cause] = 0xff00;
		return;
	}
	switch (IR.list.opType)
	{
	case 0x01: // Int指令集取数
		idI();
		break;
	}
}
inline void Control::execute() const
{
	if (Error) // 指令错误
		return;
	uint8_t flags;
	switch (IR.list.opType)
	{
	case 0x01: // Int指令集执行
		switch (IR.list.opVal)
		{
		case 0x01: // mov
			break;
		case 0x02: // calc
			iregs[IR.list.rd] = ALU<uint64_t>(IR.list.op2);
			break;
		case 0x10: // load
			IMMs[MAR] = IMMs[IX] + IMMs[IY];
			membus.addtrans(Priv ? (R | P) : R);
			break;
		case 0x11: // store
			IMMs[MAR] = IMMs[IX] + IMMs[IY];
			membus.addtrans(Priv ? (W | P) : W);
			IMMs[MDR] = iregs[IR.list.rd];
			break;
		case 0x18: // in
			IMMs[MAR] = IMMs[IX];
			break;
		case 0x19: // out
			IMMs[MAR] = IMMs[IX];
			IMMs[MDR] = iregs[IR.list.rd];
			break;
		case 0x20: // jmp&branch
			flags = sregs[Status] & 0x07;
			if (flags & (IR.list.op2 & 0x07))
				sregs[Code] = IMMs[IX];
			break;
		case 0x21:					 // call&ret
			if (IR.list.op2 == 0x01) // call
			// 压栈内容：返回地址寄存器
			{
				IMMs[MAR] = iregs[Stack];
				membus.addtrans(Priv ? (W | P) : W);
				IMMs[MDR] = iregs[Return];
				membus.write(8);
				iregs[Stack] -= 8;
				iregs[Return] = sregs[Code];
				sregs[Code] = IMMs[IX];
			}
			else if (IR.list.op2 == 0xff) // ret
			// 弹栈内容：返回地址寄存器
			{
				IMMs[MAR] = iregs[Stack];
				membus.addtrans(Priv ? (R | P) : R);
				membus.read(8);
				iregs[Stack] += 8;
				sregs[Code] = iregs[Return];
				iregs[Return] = IMMs[MDR];
				iregs[Stack] += IR.list.imm; // 丢弃n个字节的栈空间
			}
			else
			{
				// 错误的操作码
				Error = true;
				return;
			}
			break;
		case 0x40: // spec
			switch (IR.list.op2)
			{
			case 0x00: // ecall
				// environment call，陷入指令
				// 此过程填入Cause值并屏蔽中断，其余交给 post环节
				sregs[Status] &= ~(1 << 8); // 中断禁用
				sregs[Cause] = IR.list.imm;
				break;
			case 0x01: // eret
				// environment return，返回指令
				// 需要出栈的内容：Status，Stack寄存器
				// 执行时屏蔽中断，结束后解除屏蔽
				sregs[Status] &= ~(1 << 8); // 中断禁用
				IMMs[MAR] = iregs[Stack];
				membus.addtrans(Priv ? (R | P) : R);
				membus.read(8);
				iregs[Stack] += 8;
				iregs[Status] = IMMs[MDR];
				IMMs[MAR] = iregs[Stack];
				membus.addtrans(Priv ? (R | P) : R);
				membus.read(8);
				iregs[Stack] += IMMs[MDR];
				sregs[Status] |= ((unsigned long long)1 << 8); // 中断启用
				break;
			case 0x08: // kload
				// 从通用寄存器加载到特殊寄存器
				sregs[IR.list.rd] = iregs[IR.list.rs1];
				break;
			case 0x09: // kstore
				// 从特殊寄存器加载到通用寄存器
				iregs[IR.list.rd] = sregs[IR.list.rs1];
				break;
			default: // 错误的操作码
				Error = true;
				sregs[Cause] = 0xff03;
				break;
			}
		case 0xff: // HALT
			sregs[Status] |= ((unsigned long long)1 << 17);
			break;
		default: // 错误的指令码
			Error = true;
			sregs[Cause] = 0xff02;
			break;
		}
		break;
	}
}
void Control::memory() const
{
	if (Error) // 指令错误
		return;
	switch (IR.list.opType)
	{
	case 0x01: // Int指令集内存访问
		switch (IR.list.opVal)
		{
		case 0x10: // load
			membus.read(IR.list.op2);
			iregs[IR.list.rd] = IMMs[MDR];
			break;
		case 0x11: // store
			membus.write(IR.list.op2);
			break;
		case 0x18: // in
			membus.readIO();
			iregs[IR.list.rd] = IMMs[MDR];
			break;
		case 0x19: // out
			membus.writeIO();
			break;
		default: // 错误的指令码
			Error = true;
			sregs[Cause] = 0xff02;
			break;
		}
	}
}
void Control::post()
{
	// 状态标记更新
	Priv = sregs[Status] & ((unsigned long long)1 << 10);
	// 中断和异常处理
	if (sregs[Cause] != 0) // 中断标号不为空，存在中断
	{
		IMMs[MAR] = sregs[Cause] > 0xff00 ? (sregs[EDTR] + (sregs[Cause] & 0xff)) : (sregs[IDTR] + sregs[Cause]);
		membus.read(8);
		if (IMMs[MDR] & ((unsigned long long)0xffff << 48))
		{
			Priv = true;
			sregs[Status] |= ((unsigned long long)Priv << 8);
		}
		// 中断启用
		sregs[Status] |= ((unsigned long long)1 << 8);
		iregs[31] = sregs[Cause];
	}
}

void Control::mainLoop() // 主循环
{
	while (!(sregs[Status] & ((unsigned long long)1 << 17)))
	{ // 读取指令
		fetch();
		if (!Error)
			// 解码指令
			decode();
		if (!Error)
			// 执行指令
			execute();
		if (!Error)
			// 访问内存
			memory();
		// 后处理
		post();
	}
}